package com.tao.config;


import com.tao.filter.JwtAuthenticationTokenFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @Author 季伟
 * 功能：
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;
    @Autowired
    private AccessDeniedHandler accessDeniedHandler;

    /**
     * 配置密码加密方法，当使用这个方法将一个passwordEncoder注入到sprig容器中时spring security会自动修改他的加密方法
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()//关闭csrf
                /*不会创建session并且不从session中获取上下文内容，
                  因为是通过jwt的token手动实现，并且由于前后端分离没有携带cookie，session也因此失效
                */
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                //设置登录接口不进行验证
                .antMatchers("/login").permitAll()
                .antMatchers("/assist").permitAll()
                .antMatchers("/logout").authenticated()
                .antMatchers("/isLogin").authenticated()
                .antMatchers("/message").authenticated()
                //其余的全部不验证
                .anyRequest().permitAll();
        //关闭默认的登出接口/logout，使之让给我自定义的controller
        http.logout().disable();
        //关闭默认的/login
         http.formLogin().disable();
        //将自定义的jwt验证过滤器加到springSecurity过滤链的前面
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        //配置异常处理
        http.exceptionHandling()
                //用户认证异常处理
                .authenticationEntryPoint(authenticationEntryPoint)
                //权限认证异常处理
                .accessDeniedHandler(accessDeniedHandler);
        //允许跨域，因为前后端部署在两个端口上会有跨域问题
        http.cors();

    }
}
